package com.heima.article.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.common.cache.CacheService;
import com.heima.common.constants.ArticleConstants;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.HotArticleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private ApArticleMapper apArticleMapper;

    @Autowired
    private CacheService cacheService;

    @Override
    public void computeHotArticle() {
        //1 查询五天内的文章
        LocalDateTime dateTime = LocalDateTime.now().minusDays(5);
        Date date = Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
        List<ApArticle> articleListByLast5days = apArticleMapper.findArticleListByLast5days(date);
        if (CollectionUtil.isEmpty(articleListByLast5days)) {
            log.info("近五天没有新闻");
            return;
        }


        //2 计算合集中所有所有文章的总热度
        List<HotArticleVo> hotArticleVos = computeScore(articleListByLast5days);
        if (CollectionUtils.isEmpty(hotArticleVos)){
            return;
        }

        //3分组后并进行缓存
            groupAndCache(hotArticleVos);

    }
    private void groupAndCache(List<HotArticleVo> hotArticleVos){
        //按频道分组缓存
        List<List<HotArticleVo>> listGroupByChannel = CollectionUtil.groupByField(hotArticleVos,"channelId");
        if (CollectionUtil.isEmpty(listGroupByChannel)){
            return;
        }
        for (List<HotArticleVo> list : listGroupByChannel) {
            if (CollectionUtil.isEmpty(list)){
                continue;
            }
            Integer channelId = list.get(0).getChannelId();
            sortedAndCache(list,ArticleConstants.LOADTYPE_LOAD_MORE + channelId.toString());
        }
        //推荐频道的缓存
        sortedAndCache(hotArticleVos,ArticleConstants.LOADTYPE_LOAD_MORE + ArticleConstants.DEFAULT_TAG);

    }

    private void sortedAndCache(List<HotArticleVo> hotArticleVos,String key){
        if (CollectionUtils.isEmpty(hotArticleVos) || StringUtils.isEmpty(key)){
            return;
        }
        hotArticleVos = hotArticleVos.stream().sorted(Comparator.comparing(HotArticleVo::getScore).reversed()).collect(Collectors.toList());

        //截取30条
        if (hotArticleVos.size() >30){
            hotArticleVos = hotArticleVos.subList(0,30);
        }
            cacheService.set(key, JSON.toJSONString(hotArticleVos));
    }

    private List<HotArticleVo> computeScore(List<ApArticle> list) {
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        //组装新的出参结构
        ArrayList<HotArticleVo> voArrayList = new ArrayList<>();
        //遍历所有文章
        for (ApArticle apArticle : list) {
            if (apArticle == null) {
                continue;
            }
            //计算得分
            HotArticleVo vo = compute(apArticle);
            if (vo == null) {
                continue;
            }
            voArrayList.add(vo);
        }
        return voArrayList;
    }

    private HotArticleVo compute(ApArticle apArticle) {
        if (apArticle == null) {
            return null;
        }

        Integer comment = apArticle.getComment();
        Integer likes = apArticle.getLikes();
        Integer views = apArticle.getViews();
        Integer collection = apArticle.getCollection();
        Integer score = 0;
        if (views != null) {
            score += views;
        }
        if (likes != null) {
            score += (ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT * likes);
        }
        if (comment != null){
            score+=(ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT *comment);
        }
        if (collection != null){
            score += (ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT * collection);
        }

        HotArticleVo vo = new HotArticleVo();
        BeanUtils.copyProperties(apArticle,vo);
        vo.setScore(score);
        return vo;

    }
}
